home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / role / larn.lha / diag.c < prev    next >
C/C++ Source or Header  |  1995-11-19  |  14KB  |  441 lines

  1. /* diag.c */
  2. #ifdef VMS
  3. # include <types.h>
  4. # include <stat.h>
  5. #else
  6. # include <sys/types.h>
  7. # include <sys/stat.h>
  8. #endif VMS
  9.  
  10. #ifndef AMIGA
  11. # ifndef MSDOS
  12. #  ifndef VMS
  13. #   include <sys/times.h>
  14.   static struct tms cputime;
  15. #  endif VMS
  16. # endif MSDOS
  17. #endif AMIGA
  18.  
  19. #include "header.h"
  20. #include "larndefs.h"
  21. #include "monsters.h"
  22. #include "objects.h"
  23. #include "player.h"
  24.  
  25. extern long int initialtime;
  26. extern int rmst,maxitm,lasttime;
  27. extern char nosignal;
  28.  
  29. /*
  30.     ***************************
  31.     DIAG -- dungeon diagnostics
  32.     ***************************
  33.  
  34.     subroutine to print out data for debugging
  35.  */
  36. #ifdef EXTRA
  37. static int rndcount[16];
  38. diag()
  39.     {
  40.     register int i,j;
  41.     int hit,dam;
  42.     cursors();  lwclose();
  43.     if (lcreat(diagfile) < 0)   /*  open the diagnostic file    */
  44.         {
  45.         lcreat((char*)0); lprcat("\ndiagnostic failure\n"); return(-1);
  46.         }
  47.  
  48.     write(1,"\nDiagnosing . . .\n",18);
  49.     lprcat("\n\nBeginning of DIAG diagnostics ----------\n");
  50.  
  51. /*  for the character attributes    */
  52.  
  53.     lprintf("\n\nPlayer attributes:\n\nHit points: %2d(%2d)",(long)c[HP],(long)c[HPMAX]);
  54.     lprintf("\ngold: %d  Experience: %d  Character level: %d  Level in caverns: %d",
  55.         (long)c[GOLD],(long)c[EXPERIENCE],(long)c[LEVEL],(long)level);
  56.     lprintf("\nTotal types of monsters: %d",(long)MAXMONST+8);
  57.  
  58.     lprcat("\f\nHere's the dungeon:\n\n");
  59.  
  60.     i=level;
  61.     for (j=0; j<MAXLEVEL+MAXVLEVEL; j++)
  62.         {
  63.         newcavelevel(j);
  64.         lprintf("\nMaze for level %s:\n",levelname[level]);
  65.         diagdrawscreen();
  66.         }
  67.     newcavelevel(i);
  68.  
  69.     lprcat("\f\nNow for the monster data:\n\n");
  70.     lprcat("   Monster Name      LEV  AC   DAM  ATT  DEF    GOLD   HP     EXP   \n");
  71.     lprcat("--------------------------------------------------------------------------\n");
  72.     for (i=0; i<=MAXMONST+8; i++)
  73.         {
  74.         lprintf("%19s  %2d  %3d ",monster[i].name,(long)monster[i].level,(long)monster[i].armorclass);
  75.         lprintf(" %3d  %3d  %3d  ",(long)monster[i].damage,(long)monster[i].attack,(long)monster[i].defense);
  76.         lprintf("%6d  %3d   %6d\n",(long)monster[i].gold,(long)monster[i].hitpoints,(long)monster[i].experience);
  77.         }
  78.  
  79.     lprcat("\n\nHere's a Table for the to hit percentages\n");
  80.     lprcat("\n     We will be assuming that players level = 2 * monster level");
  81.     lprcat("\n     and that the players dexterity and strength are 16.");
  82.     lprcat("\n    to hit: if (rnd(22) < (2[monst AC] + your level + dex + WC/8 -1)/2) then hit");
  83.     lprcat("\n    damage = rund(8) + WC/2 + STR - c[HARDGAME] - 4");
  84.     lprcat("\n    to hit:  if rnd(22) < to hit  then player hits\n");
  85.     lprcat("\n    Each entry is as follows:  to hit / damage / number hits to kill\n");
  86.     lprcat("\n          monster     WC = 4         WC = 20        WC = 40");
  87.     lprcat("\n---------------------------------------------------------------");
  88.     for (i=0; i<=MAXMONST+8; i++)
  89.         {
  90.         hit = 2*monster[i].armorclass+2*monster[i].level+16;
  91.         dam = 16 - c[HARDGAME];
  92.         lprintf("\n%20s   %2d/%2d/%2d       %2d/%2d/%2d       %2d/%2d/%2d",
  93.                     monster[i].name,
  94.                     (long)(hit/2),(long)max(0,dam+2),(long)(monster[i].hitpoints/(dam+2)+1),
  95.                     (long)((hit+2)/2),(long)max(0,dam+10),(long)(monster[i].hitpoints/(dam+10)+1),
  96.                     (long)((hit+5)/2),(long)max(0,dam+20),(long)(monster[i].hitpoints/(dam+20)+1));
  97.         }
  98.  
  99.     lprcat("\n\nHere's the list of available potions:\n\n");
  100.     for (i=0; i<MAXPOTION; i++) lprintf("%20s\n",&potionname[i][1]);
  101.     lprcat("\n\nHere's the list of available scrolls:\n\n");
  102.     for (i=0; i<MAXSCROLL; i++) lprintf("%20s\n",&scrollname[i][1]);
  103.     lprcat("\n\nHere's the spell list:\n\n");
  104.     lprcat("spell          name           description\n");
  105.     lprcat("-------------------------------------------------------------------------------------------\n\n");
  106.     for (j=0; j<SPNUM; j++)
  107.         {
  108.         lprc(' ');  lprcat(spelcode[j]);
  109.         lprintf(" %21s  %s\n",spelname[j],speldescript[j]); 
  110.         }
  111.  
  112.     lprcat("\n\nFor the c[] array:\n");
  113.     for (j=0; j<100; j+=10)
  114.         {
  115.         lprintf("\nc[%2d] = ",(long)j); for (i=0; i<9; i++) lprintf("%5d ",(long)c[i+j]);
  116.         }
  117.  
  118.     lprcat("\n\nTest of random number generator ----------------");
  119.     lprcat("\n    for 25,000 calls divided into 16 slots\n\n");
  120.  
  121.     for (i=0; i<16; i++)  rndcount[i]=0;
  122.     for (i=0; i<25000; i++) rndcount[rund(16)]++;
  123.     for (i=0; i<16; i++)  { lprintf("  %5d",(long)rndcount[i]); if (i==7) lprc('\n'); }
  124.  
  125.     lprcat("\n\n");         lwclose();
  126.     lcreat((char*)0);       lprcat("Done Diagnosing . . .");
  127.     return(0);
  128.     }
  129. /*
  130.     subroutine to count the number of occurrences of an object
  131.  */
  132. dcount(l)
  133.     int l;
  134.     {
  135.     register int i,j,p;
  136.     int k;
  137.     k=0;
  138.     for (i=0; i<MAXX; i++)
  139.         for (j=0; j<MAXY; j++)
  140.             for (p=0; p<MAXLEVEL; p++)
  141.                 if (cell[(long) p*MAXX*MAXY+i*MAXY+j].item == l) k++;
  142.     return(k);
  143.     }
  144.  
  145. /*
  146.     subroutine to draw the whole screen as the player knows it
  147.  */
  148. diagdrawscreen()
  149.     {
  150.     register int i,j,k;
  151.  
  152.     for (i=0; i<MAXY; i++)
  153.  
  154. /*  for the east west walls of this line    */
  155.         {
  156.         for (j=0; j<MAXX; j++)  if (k=mitem[j][i]) lprc(monstnamelist[k]); else
  157.                                 lprc(objnamelist[item[j][i]]);
  158.         lprc('\n');
  159.         }
  160.     }
  161. #endif
  162.  
  163. /*
  164.     to save the game in a file
  165.  */
  166. static long int zzz=0;
  167. savegame(fname)
  168.     char *fname;
  169.     {
  170.     extern char lastmonst[], course[];
  171.     register int i,k;
  172.     register struct sphere *sp;
  173.     struct stat statbuf;
  174. # ifdef MSDOS
  175.     struct  cel buf[MAXX];
  176.     RAMBLOCK    *rp;
  177.     DISKBLOCK   *dp;
  178. # endif
  179.  
  180.     nosignal=1;  lflush();  savelevel();
  181.     ointerest();
  182.     if (lcreat(fname) < 0)
  183.         {
  184.         lcreat((char*)0); lprintf("\nCan't open file <%s> to save game\n",fname);
  185.         nosignal=0;  return(-1);
  186.         }
  187.  
  188.     set_score_output();
  189.  
  190. # ifdef MSDOS
  191.     lwrite((char*)beenhere,MAXLEVEL+MAXVLEVEL);
  192.  
  193.     /* Some levels may be out on disk, some are in memory.
  194.      */
  195.     for (k = 0; k < MAXLEVEL + MAXVLEVEL; k++)
  196.         if (beenhere[k]) {
  197.  
  198.             /* Is the level in memory already ?
  199.              */
  200.             for (rp = ramblks; rp; rp = rp->next)
  201.                 if (rp->level == k)
  202.                     break;
  203.             if (rp != NULL) {
  204.                 lwrite((char *) &rp->gtime, sizeof (long));
  205.                 warn(" %d", k);
  206. # ifdef ndef
  207.                 warn("From memory\n", k);
  208. # endif
  209.                 lwrite((char *) rp->cell, sizeof rp->cell);
  210.                 continue;
  211.             }
  212.  
  213.             /* Is it on disk ?
  214.              */
  215.             for (dp = diskblks; dp; dp = dp->next)
  216.                 if (dp->level == k)
  217.                     break;
  218.  
  219.             if (dp == NULL) {
  220.                 levelinfo();
  221.                 error("Level %d is neither in memory nor on disk\n", k);
  222.             }
  223.  
  224.             /* Copy the contents of the SWAPFILE */
  225.             lwrite((char *) &dp->gtime, sizeof (long));
  226. # ifdef ndef
  227.             warn("From swap file...\n", k);
  228. # endif
  229.             warn(" %ds", k);
  230.             if (lseek(swapfd, dp->fpos, 0) < 0) {
  231.                 warn("Can't seek to %ld\n", dp->fpos);
  232.                 return -1;
  233.             }
  234.             for (i = 0; i < MAXY; i++) {
  235. # ifdef ndef
  236.                 warn("Copying swap file...\n");
  237. # endif
  238.                 if (vread(swapfd, (char *) buf, sizeof buf) !=
  239.                     sizeof buf) {
  240.                     warn("Swap file short!\n");
  241.                     return -1;
  242.                 }
  243.                 lwrite((char *) buf, sizeof buf);
  244.             }
  245.         }
  246. # else
  247.     lwrite((char*)beenhere,MAXLEVEL+MAXVLEVEL);
  248.     for (k=0; k<MAXLEVEL+MAXVLEVEL; k++)
  249.         if (beenhere[k])
  250.             lwrite((char*)&cell[(long) k*MAXX*MAXY],sizeof(struct cel)*MAXY*MAXX);
  251. # endif
  252.  
  253. #ifndef AMIGA
  254. # ifndef VMS
  255. #  ifndef MSDOS
  256.     times(&cputime);    /* get cpu time */
  257.     c[CPUTIME] += (cputime.tms_utime+cputime.tms_stime)/60;
  258. #  endif MSDOS
  259. # endif VMS
  260. #endif AMIGA
  261.  
  262.     lwrite((char*)&c[0],100*sizeof(long));
  263.     lprint((long)gtime);        lprc(level);
  264.     lprc(playerx);      lprc(playery);
  265.     lwrite((char*)iven,26); lwrite((char*)ivenarg,26*sizeof(short));
  266.     for (k=0; k<MAXSCROLL; k++)  lprc(scrollname[k][0]);
  267.     for (k=0; k<MAXPOTION; k++)  lprc(potionname[k][0]);
  268.     lwrite((char*)spelknow,SPNUM);       lprc(wizard);
  269.     lprc(rmst);     /*  random monster generation counter */
  270.     for (i=0; i<90; i++)    lprc(itm[i].qty);
  271.     lwrite((char*)course,25);           lprc(cheat);        lprc(VERSION);
  272.     for (i=0; i<MAXMONST; i++) lprc(monster[i].genocided); /* genocide info */
  273.     for (sp=spheres; sp; sp=sp->p)
  274.         lwrite((char*)sp,sizeof(struct sphere));    /* save spheres of annihilation */
  275.     time(&zzz);         lprint((long)(zzz-initialtime));
  276.     lwrite((char*)&zzz,sizeof(long));
  277. # ifndef MSDOS
  278. #ifdef AMIGA
  279.     if(stat(fname, &statbuf) < 0)
  280. #else
  281.     if(fstat(lfd,&statbuf) < 0)
  282. #endif /* AMIGA */
  283.       lprint(0L);
  284.     else lprint((long)statbuf.st_ino); /* inode # */
  285. # endif
  286.  
  287.     lwclose();  lastmonst[0] = 0;
  288. #ifndef VT100
  289.     setscroll();
  290. #endif VT100
  291.     lcreat((char*)0);  nosignal=0;
  292.     return(0);
  293.     }
  294.  
  295. restoregame(fname)
  296.     char *fname;
  297.     {
  298.     register int i,k;
  299.     register struct sphere *sp,*sp2;
  300.     struct stat filetimes;
  301. # ifdef MSDOS
  302.     RAMBLOCK    *rp, *getramblk();
  303. # endif
  304.  
  305.     cursors(); lprcat("\nRestoring . . .");  lflush();
  306.     if (lopen(fname) <= 0)
  307.         {
  308.         lcreat((char*)0); lprintf("\nCan't open file <%s>to restore game\n",fname);
  309.         nap(2000); c[GOLD]=c[BANKACCOUNT]=0;  died(-265); return;
  310.         }
  311.     lrfill((char*)beenhere,MAXLEVEL+MAXVLEVEL);
  312.  
  313. # ifdef MSDOS
  314.     /* As levels get read in from the save file, store them away
  315.      * by calling putsavelevel.
  316.      */
  317.     for (k = 0; k < MAXLEVEL + MAXVLEVEL; k++)
  318.         if (beenhere[k]) {
  319.             rp = getramblk(k);
  320.             lrfill((char *) &rp->gtime, sizeof (long));
  321.             lrfill((char *) rp->cell, sizeof rp->cell);
  322.             rp->level = k;
  323.         }
  324. # else
  325.     for (k=0; k<MAXLEVEL+MAXVLEVEL; k++)
  326.         if (beenhere[k])
  327.             lrfill((char*)&cell[(long) k*MAXX*MAXY],sizeof(struct cel)*MAXY*MAXX);
  328. # endif
  329.  
  330.     lrfill((char*)&c[0],100*sizeof(long));  gtime = lrint();
  331.     level = c[CAVELEVEL] = lgetc();
  332.     playerx = lgetc();      playery = lgetc();
  333.     lrfill((char*)iven,26);     lrfill((char*)ivenarg,26*sizeof(short));
  334.     for (k=0; k<MAXSCROLL; k++)  scrollname[k][0] = lgetc();
  335.     for (k=0; k<MAXPOTION; k++)  potionname[k][0] = lgetc();
  336.     lrfill((char*)spelknow,SPNUM);      wizard = lgetc();
  337.     rmst = lgetc();         /*  random monster creation flag */
  338.  
  339.     for (i=0; i<90; i++)    itm[i].qty = lgetc();
  340.     lrfill((char*)course,25);           cheat = lgetc();
  341.     if (VERSION != lgetc())     /*  version number  */
  342.         {
  343.         cheat=1;
  344.         lprcat("Sorry, But your save file is for an older version of larn\n");
  345.         nap(2000); c[GOLD]=c[BANKACCOUNT]=0;  died(-266); return;
  346.         }
  347.  
  348.     for (i=0; i<MAXMONST; i++) monster[i].genocided=lgetc(); /* genocide info */
  349.     for (sp=0,i=0; i<c[SPHCAST]; i++)
  350.         {
  351.         sp2 = sp;
  352.         sp = (struct sphere *)malloc(sizeof(struct sphere));
  353.         if (sp==0) { write(2,"Can't malloc() for sphere space\n",32); break; }
  354.         lrfill((char*)sp,sizeof(struct sphere));    /* get spheres of annihilation */
  355.         sp->p=0;    /* null out pointer */
  356.         if (i==0) spheres=sp;   /* beginning of list */
  357.             else sp2->p = sp;
  358.         }
  359.  
  360.     time(&zzz);
  361.     initialtime = zzz-lrint();
  362. #ifdef AMIGA
  363.     stat(fname, &filetimes);
  364. #else
  365.     fstat(fd,&filetimes);   /*  get the creation and modification time of file  */
  366. #endif /* AMIGA */
  367.     lrfill((char*)&zzz,sizeof(long));   zzz += 6;
  368.     if (filetimes.st_ctime > zzz) fsorry(); /*  file create time    */
  369.     else if (filetimes.st_mtime > zzz) fsorry(); /* file modify time    */
  370.     if (c[HP]<0) { died(284); return; } /* died a post mortem death */
  371.  
  372.     oldx = oldy = 0;
  373. #ifndef VMS
  374. # ifndef MSDOS
  375.     i = lrint();  /* inode # */
  376.     if (i && (filetimes.st_ino!=i)) fsorry();
  377. # endif MSDOS
  378. #endif VMS
  379.     lrclose();
  380.     if (strcmp(fname,ckpfile) == 0)
  381.         {
  382.         if (lappend(fname) < 0) fcheat();  else { lprc(' '); lwclose(); }
  383.         lcreat((char*)0);
  384.         }
  385.     else if (unlink(fname) < 0) fcheat(); /* can't unlink save file */
  386. /*  for the greedy cheater checker  */
  387.     for (k=0; k<6; k++) if (c[k]>99) greedy();
  388.     if (c[HPMAX]>999 || c[SPELLMAX]>125) greedy();
  389.     if (c[LEVEL]==25 && c[EXPERIENCE]>skill[24]) /* if patch up lev 25 player */
  390.         {
  391.         long tmp;
  392.         tmp = c[EXPERIENCE]-skill[24]; /* amount to go up */
  393.         c[EXPERIENCE] = skill[24];
  394.         raiseexperience((long)tmp);
  395.         }
  396.     getlevel();  lasttime=gtime;
  397.     }
  398.  
  399. /*
  400.     subroutine to not allow greedy cheaters
  401.  */
  402. static greedy()
  403.     {
  404. #if WIZID
  405.     if (wizard) return;
  406. #endif
  407.  
  408.     lprcat("\n\nI am so sorry, but your character is a little TOO good!  Since this\n");
  409.     lprcat("cannot normally happen from an honest game, I must assume that you cheated.\n");
  410.     lprcat("In that you are GREEDY as well as a CHEATER, I cannot allow this game\n");
  411.     lprcat("to continue.\n"); nap(5000);  c[GOLD]=c[BANKACCOUNT]=0;  died(-267); return;
  412.     }
  413.  
  414. /*
  415.     subroutine to not allow altered save files and terminate the attempted
  416.     restart
  417.  */
  418. static fsorry()
  419.     {
  420.     lprcat("\nSorry, but your savefile has been altered.\n");
  421.     lprcat("However, seeing as I am a good sport, I will let you play.\n");
  422.     lprcat("Be advised though, you won't be placed on the normal scoreboard.");
  423.     cheat = 1;  nap(4000);
  424.     }
  425.  
  426. /*
  427.     subroutine to not allow game if save file can't be deleted
  428.  */
  429. static fcheat()
  430.     {
  431. #if WIZID
  432.     if (wizard) return;
  433. #endif
  434.  
  435.     lprcat("\nSorry, but your savefile can't be deleted.  This can only mean\n");
  436.     lprcat("that you tried to CHEAT by protecting the directory the savefile\n");
  437.     lprcat("is in.  Since this is unfair to the rest of the larn community, I\n");
  438.     lprcat("cannot let you play this game.\n");
  439.     nap(5000);  c[GOLD]=c[BANKACCOUNT]=0;  died(-268); return;
  440.     }
  441.